/*

  The contents of this file are subject to the Mozilla Public License Version
  1.1 (the "License"); you may not use this file except in compliance with
  the License. You may obtain a copy of the License at 
  
           http://www.mozilla.org/MPL/ 
  
  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  for the specific language governing rights and limitations under the License. 
  
  The Original Code is Tamina Framework.
  
  The Initial Developer of the Original Code is
  MOUTON David (aka damo)  <damo@tamina-online.com>.
  Portions created by the Initial Developer are Copyright (C) 2004-2007
  the Initial Developer. All Rights Reserved.
  
  Contributor(s) :
  
*/
package org.tamina.core.init
{
	/**
	 *	InitManager permet de gerer une pile d'elements à initialiser
	 *	@return	Une référence à la classe
	 */
	public const InitManager:_InitManager = new _InitManager();
	
}
	import flash.events.EventDispatcher;
	import org.tamina.core.init.IInitializable;
	import org.tamina.core.init.InitEvent;
	import com.ericfeminella.utils.HashMap;
	
	
internal class _InitManager extends EventDispatcher
{
	//Props
	private var __pool:HashMap;
	private var __isRunning:Boolean=false;
	private var __nbTotalElements:uint=0;
	
	//Constructeur
	function _InitManager(){
		__pool = new HashMap();
	}
	
	//Methodes publiques
	
	/**
	 * Rajoute un element initializable dans la pile d'initialisation
	 * @param element
	 * 
	 */	
	public function addElement(element:IInitializable):void
	{
		element.addEventListener(InitEvent.INITIALIZED,recordElementAsFinish);
		element.addEventListener(InitEvent.FAILURE,recordElementAsFailed);
		__pool.put(element.getName(),element);
	}
	
	/**
	 * Supprime un element de la pile à partir de son nom
	 * @param name
	 * 
	 */	
	public function removeElementByName(name:String):void
	{
		__pool.remove(name);
	}
	
	/**
	 * Debute l'initialization
	 * 
	 */	
	public function start():void
	{
		if(!__isRunning){
			__nbTotalElements = __pool.getKeys().length;
			__isRunning = true;
			for(var i:uint=0; i<__pool.size();i++){
				var iiObj:IInitializable = IInitializable(__pool.getValues()[i]);
				iiObj.init();
			}			
		}		
	}
	
	/**
	 * Efface la pile
	 * 
	 */	
	public function clear():void
	{
		__nbTotalElements = 0;
		__isRunning = false;
		for(var i:uint=0; i<__pool.size();i++){
			var iiObj:IInitializable = IInitializable(__pool.getValues()[i]);
			iiObj.removeEventListener(InitEvent.INITIALIZED,recordElementAsFinish);
		}
		__pool.clear();
	}
	
	/**
	 * Indique si le processus d'initialization a debuté
	 * @return 
	 * 
	 */	
	public function get isRunning():Boolean
	{
		return __isRunning;
	}
	
	/**
	 * Renvoi le pourcentage de progression
	 * @return 
	 * 
	 */	
	public function getProgressPercent():uint{
		var result:uint = (__nbTotalElements - __pool.getKeys().length)*100;
		return result;
	}
	
	//Methodes privées
	
	private function recordElementAsFinish(e:InitEvent):void
	{
		var iiObj:IInitializable = IInitializable(e.currentTarget);
		iiObj.removeEventListener(InitEvent.INITIALIZED,recordElementAsFinish);
		dispatchEvent(new InitEvent(InitEvent.INIT_ELEMENT_COMPLETE,iiObj));
		__pool.remove(iiObj.getName());
		if(__pool.isEmpty()){
			var e:InitEvent = new InitEvent(InitEvent.INIT_COMPLETE);
			dispatchEvent(e);
		}
	}
	
	private function recordElementAsFailed(e:InitEvent):void
	{
		var iiObj:IInitializable = IInitializable(e.currentTarget);
		iiObj.removeEventListener(InitEvent.INITIALIZED,recordElementAsFinish);
		iiObj.removeEventListener(InitEvent.FAILURE,recordElementAsFailed);
		dispatchEvent(new InitEvent(InitEvent.INIT_ELEMENT_FAILED,iiObj));
	}
	
}